﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace EpubFactory.Template.Domain
{
    public class ResourceCollection : IEnumerable
    {
        private const String IMAGE_PREFIX = "image_";
        private const String ITEM_PREFIX = "item_";
        private Dictionary<string, Resource> resources;

        public IEnumerator GetEnumerator()
        {
            return resources.Values.GetEnumerator();
        }
        public ResourceCollection()
        {
            resources = new Dictionary<string, Resource>();
        }
        public Resource Add(Resource resource)
        {
            FixResourceHref(resource);
            resources[resource.Href] = resource;
            return resource;
        }
        public void FixResourceId(Resource resource)
        {
            if (string.IsNullOrWhiteSpace(resource.Id))
            {
                resource.Id = CreateUniqueResourceId(resource);
            }
            else
            {
                resource.Id = MakeValidId(resource.Id, resource);
            }
        }
        private String CreateUniqueResourceId(Resource resource)
        {
            var prefix = GetResourceItemPrefix(resource);
            return prefix + resources.Values.Count;
        }
        private String GetResourceItemPrefix(Resource resource)
        {
            String result;
            if (MediaType.IsBitmapImage(resource.MediaType))
            {
                result = IMAGE_PREFIX;
            }
            else
            {
                result = ITEM_PREFIX;
            }
            return result;
        }
        private String MakeValidId(String resourceId, Resource resource)
        {
            if (!string.IsNullOrWhiteSpace(resourceId))
            {
                resourceId = GetResourceItemPrefix(resource) + resourceId;
            }
            return resourceId;
        }
        private void FixResourceHref(Resource resource)
        {
            if (string.IsNullOrWhiteSpace(resource.Href))
            {
                int i = 1;
                if (resource.MediaType == null)
                {
                    throw new InvalidOperationException("Resource must have either a MediaType or a href");
                }
                string href = CreateHref(resource.MediaType, i);
                while (resources.Any(g => g.Value.Href == href))
                {
                    href = CreateHref(resource.MediaType, ++i);
                }
                resource.Href = href;
            }
        }
        private String CreateHref(MediaType mediaType, int counter)
        {
            if (MediaType.IsBitmapImage(mediaType))
            {
                return IMAGE_PREFIX + counter + mediaType.DefaultExtension;
            }
            else
            {
                return ITEM_PREFIX + counter + mediaType.DefaultExtension;
            }
        }
    }
}
